package edu.kit.csl.cratylus.io;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import edu.kit.csl.cratylus.datatypes.Corpus;
import edu.kit.csl.cratylus.datatypes.Sentence;
import edu.kit.csl.cratylus.datatypes.SentencePair;
import edu.kit.csl.cratylus.datatypes.Word;
import edu.kit.csl.cratylus.extraction.WritingSystem;

/**
 * This corpus dumper writes a PISA alignment file. Since the PISA format does
 * not assume a writing system of the target language, we do not require one
 * here.
 */
public class PisaCorpusDumper implements CorpusDumper {

	/**
	 * Writes a PISA alignment file to the file system.
	 * 
	 * @param corpus the corpus which should be dumped
	 * @param ws not used
	 * @param fileName path to the file to write
	 * @throws IOException if the file could not be written
	 * @throws NullPointerException if one of the parameters except <code>
	 * 				ws</code> is null
	 */
	@Override
	public void dumpToFileSystem(Corpus corpus, WritingSystem ws,
			String fileName) throws IOException {
		FileWriter fs = new FileWriter(fileName);
		BufferedWriter out = new BufferedWriter(fs);
		int id = 1;
		for (SentencePair pair : corpus) {
			Sentence srcSen = pair.getSourceSentence();
			Sentence trgtSen = pair.getTargetSentence();
			out.write("# Sentence pair (" + (id++) + ") source length "
					+ srcSen.getLength() + " target length "
					+ trgtSen.getLength() + " alignment score : ?\n");
			out.write(trgtSen.toString() + "\n");
			int trgtWordId = 1;
			for (Word word : trgtSen) {
				String wordStr = "f" + (trgtWordId++);
				String pronun = word.getContent();
				int blankCount = pronun.length() 
						- wordStr.length() + 1;
				if (blankCount >= 0) {
					out.write(wordStr);
					out.write(new String(
							new char[blankCount]).replace("\0", " "));
				} else if (pronun.length() > -blankCount) {
					out.write(wordStr.substring(0, 
							wordStr.length() + blankCount));
				} else {
					Logger.getSingleton().warn("Alignment segmentation string "
						+ "generation failed");
				}
			}
			out.write("\n" + 
					generateAlignmentString(srcSen, pair.getAlignment()));
		}
		out.close();
	}

	/*
	 * Generates a GIZA++ alignment string like
	 * NULL ({ }) this ({ 1}) is ({ 2 4 }) fine ({ 3 })
	 * TODO: Could be more efficiently implemented..
	 */
	private String generateAlignmentString(Sentence srcSen, short[] align) {
		StringBuilder s = new StringBuilder();
		int i = 0;
		for (Word word : srcSen) {
			s.append(" " + word.getContent() + " ({");
			for (int j = 0; j < align.length; j++) {
				if (align[j] == i) {
					s.append(" " + (j + 1));
				}
			}
			s.append(" })");
			i++;
		}
		return s.toString().trim() + "\n";
	}
}